package cn.rui.config;

import cn.rui.shiro.realms.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * shiro的相关配置
 *
 * @author 徽州大都督
 * @date 2020/8/11
 */

@Configuration
public class ShiroConfig {


    // 下面两个方法对 注解权限起作用有很大的关系，请把这两个方法，放在配置的最上面
    @Bean
    public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    /*@Bean
    public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }*/


    //3,创建自定义的realm
    @Bean
    //@DependsOn("adminService")
    public Realm getRealm() {
        CustomerRealm realm = new CustomerRealm ();

        //修改密码凭证匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher ();
        //设置加密算法为md5
        credentialsMatcher.setHashAlgorithmName ("MD5");
        //设置散列次数
        credentialsMatcher.setHashIterations (1024);
        realm.setCredentialsMatcher (credentialsMatcher);


        //开启缓存管理
        //realm.setCacheManager (new EhCacheManager ());
        //realm.setCachingEnabled (true); //全局缓存
        //realm.setAuthenticationCachingEnabled (true); //认证缓存
        //realm.setAuthorizationCachingEnabled (true); //授权缓存

        return realm;
    }



    //2,创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager ();

        //给安全管理器设置realm
        securityManager.setRealm (getRealm());

        return securityManager;
    }



    //1,创建shiroFilter,负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean ();

        //给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager (getDefaultWebSecurityManager());

        //配置系统受限资源
        Map<String, String> map = new HashMap<> ();

        //授权
        //map.put ("/admin/findByPage/**","perms[admin:find]");

        map.put ("/admin/login", "anon");
        //map.put ("/admin/findByPage/**", "roles[user]");//设置登陆页面为公共资源,其他资源都为受限资源
        //map.put ("/admin/**/**", "authc");
        //map.put ("/admin/login/**", "anon");
        //map.put ("/user/register", "anon"); //设置登陆页面为公共资源,其他资源都为受限资源
        //map.put ("/register.jsp", "anon"); //设置注册页面为公共资源,其他资源都为受限资源
        //map.put ("/**", "authc");
        //authc请求这个资源需要认证和授权
        //anon 可以匿名访问，不需要认证和授权
        //authcBasic  指定url需要认证和授权
        //logout  登出过滤器

        //如果没有认证和授权,默认返回路径login.jsp
        //shiroFilterFactoryBean.setLoginUrl ("/login.jsp");

        shiroFilterFactoryBean.setFilterChainDefinitionMap (map);

        //为授权要访问的路径
        shiroFilterFactoryBean.setUnauthorizedUrl ("");

        //配置系统公共资源


        return shiroFilterFactoryBean;
    }



    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator =new DefaultAdvisorAutoProxyCreator ();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass (true);

        return defaultAdvisorAutoProxyCreator;
    }


    //开启shiro aop注解支持
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor ();
        authorizationAttributeSourceAdvisor.setSecurityManager (getDefaultWebSecurityManager());

        return authorizationAttributeSourceAdvisor;
    }


}
